package com.spring.utils.api_v4.controller;

import com.alibaba.fastjson.JSONObject;
import com.spring.utils.api_v4.annotation.ResponseResult;
import com.spring.utils.api_v4.controller.ui.*;
import com.spring.utils.api_v4.pojo.*;
import com.spring.utils.api_v4.pojo.response.BizException;
import com.spring.utils.api_v4.pojo.response.ResultCode;
import com.spring.utils.api_v4.pojo.salary.DeptWage;
import com.spring.utils.api_v4.pojo.salary.task.DeptWageTask;
import com.spring.utils.api_v4.pojo.salary.task.EmployeeSalaryTask;
import com.spring.utils.api_v4.pojo.salary.EmployeeWage;
import com.spring.utils.api_v4.pojo.salary.task.WageTask;
import com.spring.utils.api_v4.service.ISalaryService;
import com.spring.utils.api_v4.service.ISystemService;
import lombok.extern.java.Log;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

@RequestMapping("/api/salary")
@RestController
@ResponseResult
@Log
public class SalaryController {
    @Autowired private ISalaryService salaryService;
    @Autowired private ISystemService systemService;

    /**
     * 创建工资任务
     * @return
     */
    @GetMapping("/wage/task/create")
    public List<DeptWageItem> createWageTask(@RequestHeader String token) {
        // 如果用户不是否是管理员
        if(!systemService.hasRole(token, "admin")) {
            throw new BizException(ResultCode.NO_PERMISSION);
        };
        // 返回部门绩效列表
        return salaryService.getDeptWages().stream().map(dw -> {
            DeptWageItem dwi = new DeptWageItem();
            BeanUtils.copyProperties(dw, dwi);
            return dwi;
        }).collect(Collectors.toList());
    }

    /**
     * 创建工资任务
     * @param form
     * @return
     */
    @PostMapping("/wage/task/save")
    public int saveWageTask(@Valid @RequestBody TaskForm form) {
        // 如果存在进行中的任务
        if(salaryService.hasTaskInProgress()) {
            throw new BizException(ResultCode.TASK_IN_PROGRESS);
        }
        // 创建任务
        WageTask task = new WageTask();
        // 创建部门分任务
        List<DeptWageTask> dwts = form.getTaskDepts().stream().map(td -> {
            DeptWageTask dwt = new DeptWageTask();
            dwt.setDept(salaryService.getDeptWageById(td.getId()));
            dwt.setTotalMerit(td.getTotalWage());
            dwt.setNote(td.getNote());
            dwt.setTask(task);
            return dwt;
        }).collect(Collectors.toList());
        BeanUtils.copyProperties(form, task);
        task.setDetpTasks(dwts);
        // 保存任务
        salaryService.saveWageTask(task);
        return task.getId();
    }

    /**
     * 获取任务列表
     * @return
     */
    @GetMapping("/tasks")
    public List<WageTaskItem> getWageTaskItems() {
        // 获取任务列表
        List<WageTask> tasks = salaryService.getTasksAll(true);
        return tasks.stream().map(task -> {
            WageTaskItem wti = new WageTaskItem();
            BeanUtils.copyProperties(task, wti);
            return wti;
        }).collect(Collectors.toList());
    }

    /**
     * 修改任务状态
     * @return
     */
    @PostMapping("/task/state/change")
    public boolean changeWageTaskState(@RequestBody JSONObject object) {
        int id = object.getInteger("id");
        int state = object.getInteger("state");
        return salaryService.changeTaskState(id, state);
    }

    /**
     * 获取部门绩效工资列表
     * @return
     */
    @GetMapping("/task/depts")
    public List<DeptWageItem> getDeptsWage() {
        List<DeptWage> dws = systemService.getDeptWagesAll();
        return dws.stream().map(dw -> {
            DeptWageItem di = new DeptWageItem();
            BeanUtils.copyProperties(dw, di);
            return di;
        }).collect(Collectors.toList());
    }

    @PostMapping("/task/delete/{id}")
    public boolean deleteTask(@PathVariable int id) {
        WageTask task = salaryService.getWageTaskById(id);
        // 不能删除正在发布的任务
        if(task.getState() == 1) {
            throw new BizException(ResultCode.TASK_IN_PROGRESS);
        }
        //根据编号删除任务
        salaryService.deleteTask(id);
        return true;
    }

    /**
     * 根据编号查询任务信息
     * @param taskId
     * @return
     */
    @GetMapping("/task/info/{taskId}")
    public WageTaskItem getTaskById(@RequestHeader(name = "token")String userId, @PathVariable int taskId) {
        // 获取任务
        WageTask task = salaryService.getWageTaskById(taskId);
        if(task == null) {
            throw new BizException(ResultCode.PARAM_IS_INVALID);
        }
        // 构造返回结果
        WageTaskItem item = new WageTaskItem();
        BeanUtils.copyProperties(task, item);
        // 将部门任务列表一并返回
        List<DeptWageTaskItem> dwtis = salaryService.getDeptWageTasks(userId, taskId).stream().map(dwt -> {
            DeptWageTaskItem dwti = new DeptWageTaskItem();
            BeanUtils.copyProperties(dwt, dwti);
            return dwti;
        }).collect(Collectors.toList());
        item.setDeptWageTaskItems(dwtis);

        return item;
    }

    /**
     * 获取工资任务设置的部门绩效列表
     * @param userId
     * @param taskId
     * @return
     */
    @GetMapping("/task/dept/items")
    public List<DeptWageTaskItem> getDeptWageOfTask(@RequestHeader(name = "token")String userId, int taskId) {
        return null;
    }

    /**
     * 获取部门任务员工列表
     * @param taskId
     * @return
     */
    @PostMapping("/dept/salaries/{taskId}")
    public List<SalaryItem> getDeptSalaries(@PathVariable String taskId, @RequestHeader String token) {
        // 获取部门任务下的员工任务列表
        List<EmployeeSalaryTask> deptSalaries = salaryService.getDeptSalaries(taskId);
        // 数据格式转换
        List<SalaryItem> sis = deptSalaries.stream().map(ds -> {
            SalaryItem si = new SalaryItem();
            BeanUtils.copyProperties(ds, si);
            return si;
        }).collect(Collectors.toList());
        return sis;
    }

    /**
     * 保存部门绩效列表
     * @param taskId 任务编号
     * @param salaryItems 员工工资列表
     * @return
     */
    @PostMapping("/dept/salaries/save/{taskId}")
    public boolean saveDeptSalaries(@PathVariable String taskId, @RequestBody List<SalaryItem> salaryItems) {
        // 获取部门任务
        Optional<DeptWageTask> op = salaryService.getDeptWageTaskById(taskId);
        if(op.isEmpty()) {
            throw new BizException(ResultCode.PARAM_IS_INVALID);
        }

        DeptWageTask dwt = op.get();

        // 转换数据类型
        List<EmployeeSalaryTask> ess = salaryItems.stream().map(si -> {
            EmployeeSalaryTask es = salaryService.getEmployeeSalaryById(si.getId());
            es.setMeritPay(si.getMeritPay());
            es.setNote(si.getNote());
            return es;
        }).collect(Collectors.toList());

        dwt.setSalaryList(ess); // 设置部门工资列表
        dwt.setState(2);        // 设置部门工资任务状态为完成

        // 保存部门工资任务
        salaryService.saveDeptWageTask(dwt);
        return true;
    }

    /**
     * 查询工资任务列表
     * @param state
     * @return
     */
    @GetMapping("/tasks/list/{state}")
    public List<WageTaskItem> getTasksOfState(@PathVariable int state) {
        return getWageTaskItems().stream().filter(wti -> wti.getState() == state).collect(Collectors.toList());
    }

    /**
     * 获取用户工资信息
     * @param userId
     * @return
     */
    @GetMapping("/wage/info/{userId}")
    public EmployeeWageItem getUserWage(@PathVariable String userId) {
        EmployeeWageItem wi = new EmployeeWageItem();
        // 查询用户工资信息
        EmployeeWage employeeWage = salaryService.getUserWage(userId);
        BeanUtils.copyProperties(employeeWage, wi);
        return wi;
    }

    /**
     * 保存工资信息
     * @param wage
     * @return
     */
    @PostMapping("/wage/save")
    public boolean saveUserWage(@RequestBody EmployeeWageItem wage) {
        EmployeeWage wg = salaryService.getWageById(wage.getId());
        if(wg == null){
            throw new BizException(ResultCode.USER_NOT_EXIST);
        }
        wage.setUserInfo(wg.getUserInfo());
        BeanUtils.copyProperties(wage, wg);
        salaryService.saveWage(wg);
        return true;
    }

    /**
     * 获取指定任务的工资列表
     * @param taskId
     * @return
     */
    @GetMapping("/wage/list/{taskId}")
    public List<JSONObject> getWagesOfTask1(@PathVariable int taskId) {
        WageTask task = salaryService.getWageTaskById(taskId);
        List<EmployeeSalaryTask> list = salaryService.getWagesOfTask(task);
        return list.stream().map(es -> {
            JSONObject obj = new JSONObject(new LinkedHashMap<>());
            obj.put("姓名", es.getUserInfo().getName());    // 姓名
            obj.put("性别", es.getUserInfo().getSex());     // 性别
            obj.put("年龄", es.getUserInfo().getAge());     // 年龄
            obj.put("部门", es.getUserInfo().getDepart().getName());    // 部门
            obj.put("岗位工资", es.getPosPay());            // 岗位工资
            obj.put("薪级工资", es.getSalaryPay());         // 薪级工资
            obj.put("提高10", es.getRatio());              // 提高10%
            obj.put("绩效工资", es.getMonthMerit());        // 绩效工资
            obj.put("年终奖", es.getYearMerit());          // 年终奖
            obj.put("超课时费", es.getExtraLessonMerit());  // 超课时费
            obj.put("辅导员津贴", es.getCounsellorAllowance());   // 辅导员津贴
            obj.put("专项奖惩", es.getSpecialMerit());      // 专项奖惩
            obj.put("加班费", es.getOvertimeMerit());      // 加班费
            obj.put("改革性补贴", es.getReformPay());        // 改革性补贴
            obj.put("工改保留", es.getReservePart());       // 工改保留
            obj.put("2000年1月1日参加工作补贴", es.getNewEmpSubsidy());  // 2000年1月1日参加工作补贴
            obj.put("人才引进补贴", es.getTalentIntroPay());  // 人才引进补贴
            obj.put("专业带头人补助", es.getProLeaderPay());   // 专业带头人补助
            obj.put("室主任津贴", es.getOfficeDirectorPay());    // 室主任津贴
            obj.put("技师津贴", es.getTechnicianPay());     // 技师津贴
            obj.put("卫生防疫津贴", es.getEpidemicPay());     // 卫生防疫津贴
            obj.put("护龄津贴", es.getNursePay());          // 护龄津贴
            obj.put("安保人员特岗津贴", es.getSecurityPay());   // 安保人员特岗津贴
            obj.put("安保人员特岗值班加班费", es.getSecurityOverPay());    // 安保人员特岗值班加班费
            obj.put("保密津贴", es.getSecretPay());         // 保密津贴
            obj.put("专职司机工作补贴", es.getDriverPay());     // 专职司机工作补贴
            obj.put("思政教师岗位津贴", es.getPoliticTeacherPay()); // 思政教师岗位津贴
            obj.put("独子费", es.getOnlyChildPay());   // 独子费
            obj.put("考务费", es.getExamPay());                // 考务费
            obj.put("交通补助", es.getTrafficPay());            // 交通补助
            obj.put("养老保险", es.getEndowmentIns());          // 养老保险
            obj.put("职业年金", es.getCareerIns());             // 职业年金
            obj.put("医疗保险", es.getMedicalIns());            // 医疗保险
            obj.put("失业保险", es.getUnemploymentIns());       // 失业保险
            obj.put("住房公积金", es.getHousingProvidentFund());  // 住房公积金
            return obj;
        }).collect(Collectors.toList());
    }

    /**
     * 查询部门绩效列表
     * @return
     */
    @GetMapping("/dept/wages")
    public List<DeptWageItem> getDeptWages() {
        List<DeptWage> dws = salaryService.getDeptWages();  // 查询部门绩效列表
        return dws.stream().map(dw -> {
            DeptWageItem dwi = new DeptWageItem();
            BeanUtils.copyProperties(dw, dwi);
            return dwi;
        }).collect(Collectors.toList());
    }

    /**
     * 保存部门绩效
     * @param deptWage
     * @return
     */
    @PostMapping("/dept/wage/save")
    public int saveDeptWage(@Valid @RequestBody DeptWageItem deptWage) {
        // 查询部门信息
        DeptInfo dept = systemService.getDeptById(deptWage.getId());
        if(dept == null) {
            throw new BizException(ResultCode.DEPARTMENT_NOT_EXIST);
        }
        // 查询部门绩效信息
        DeptWage dw = salaryService.getDeptWageById(deptWage.getId());
        if(dw == null) {
            dw = new DeptWage();
        }
        dw.setId(deptWage.getId());
        dw.setName(dept.getName());
        dw.setNote(deptWage.getNote());
        dw.setMeritPay(deptWage.getMeritPay());
        dw.setClerk(systemService.findUserById(deptWage.getClerkId()));
        salaryService.saveDeptWage(dw);
        return dw.getId();
    }

    /**
     * 删除部门绩效
     * @param id
     * @return
     */
    @DeleteMapping("/dept/wage/delete/{id}")
    public boolean deleteDeptWage(@PathVariable int id) {
        salaryService.deleteDeptWageById(id);
        return true;
    }

    /**
     * 删除员工工资信息
     * @param id
     * @return
     */
    @DeleteMapping("/employee/wage/delete/{id}")
    public boolean deleteEmployeeWage(@PathVariable String id) {
        // 根据编号删除员工工资信息
        salaryService.deleteEmployeeWageById(id);
        return true;
    }

    /**
     * 获取指定任务的部门任务详情
     * @param taskId
     * @return
     */
    @GetMapping("/dept/wage/{taskId}")
    public List<DeptTaskItem> getDeptTasks(@RequestHeader(name = "token") String userId, @PathVariable int taskId) {
        List<DeptWageTask> dwts = salaryService.getDeptWageTasks(userId, taskId);
        return dwts.stream().map(dwt -> {
            DeptTaskItem dti = new DeptTaskItem();
            dti.setId(dwt.getId());
            dti.setDeptName(dwt.getDept().getName());
            dti.setWage(dwt.getTotalMerit() + dwt.getMeritPay());
            dti.setState(dwt.getState());
            return dti;
        }).collect(Collectors.toList());
    }

    /**
     * 重置部门任务
     * @param taskId
     * @return
     */
    @PostMapping("/dept/task/reset/{taskId}")
    public boolean resetDeptTask(@PathVariable String taskId) {
        Optional<DeptWageTask> op = salaryService.getDeptWageTaskById(taskId);
        if(op.isEmpty()) {
            throw new BizException(ResultCode.PARAM_IS_INVALID);
        }
        DeptWageTask dwt = salaryService.resetDeptWageTask(op.get());
        salaryService.resetDeptWageTask(dwt);
        return true;
    }

    /**
     * 获取部门员工工资信息列表
     * @param deptId
     * @return
     */
    @GetMapping("/employee/wage/dept/{deptId}")
    public List<EmployeeWageItem> getEmployeeWagesOfDept(@PathVariable int deptId) {
        DeptInfo dept = systemService.getDeptById(deptId);
        if(dept == null) {
            throw new BizException(ResultCode.DEPARTMENT_NOT_EXIST);
        }
        List<EmployeeWage> ews = salaryService.getEmployeeWagesOfDept(dept.getId());
        return ews.stream().map(ew -> {
            EmployeeWageItem ewi = new EmployeeWageItem();
            BeanUtils.copyProperties(ew, ewi);
            return ewi;
        }).collect(Collectors.toList());
    }

    /**
     * 获取指定任务中未设置的员工任务
     * @param taskId
     * @return
     */
    @GetMapping("/emps/unset/{taskId}")
    public List<SalaryItem> getUnsetSalaries(int taskId) {
        // 获取指定任务的未设置的个人任务列表
        return salaryService.getUnsetSalariesOfTask(taskId).stream().map(es->{
            SalaryItem si = new SalaryItem();
            BeanUtils.copyProperties(es, si);
            return si;
        }).collect(Collectors.toList());
    }

    /**
     * 获取指定任务中干部任务列表
     * @param taskId
     * @return
     */
//    @GetMapping("/cadre/list/{taskId}")
//    public List<SalaryItem> getCadreSalaries(int taskId) {
//        // 获取指定任务的干部任务列表
//        return salaryService.getCadreSalariesOfTask(taskId).stream().map(es->{
//            SalaryItem si = new SalaryItem();
//            BeanUtils.copyProperties(es, si);
//            return si;
//        }).collect(Collectors.toList());
//    }

    /**
     * 获取正在进行中的任务列表
     * @return
     */
    @GetMapping("/current/tasks")
    public List<JSONObject> getTasksInProgress() {
        // 获取正在进行中的任务，即状态为：1
        List<WageTask> tasks = salaryService.getWageTasksOfState(1);
        // 构造返回列表
        return tasks.stream().map(task -> {
            JSONObject obj = new JSONObject();
            obj.put("id", task.getId());
            obj.put("name", task.getName());
            return obj;
        }).collect(Collectors.toList());
    }

    /**
     * 获取任务中干部任务列表
     * @param taskId
     * @return
     */
    @GetMapping("/cadres/task/{taskId}")
    public List<SalaryItem> getCardresOfTask(@PathVariable int taskId) {
        return salaryService.getCadreSalariesOfTask(taskId).stream().map(es -> {
            SalaryItem si = new SalaryItem();
            BeanUtils.copyProperties(es, si);
            return si;
        }).collect(Collectors.toList());
    }

    /**
     * 保存干部绩效列表
     * @param salaries
     * @return
     */
    @PostMapping("/cadres/save")
    public boolean saveCadreMerits(@RequestBody List<SalaryItem> salaries) {
        List<EmployeeSalaryTask> ess = salaries.stream().map(si -> {
            EmployeeSalaryTask es = salaryService.getEmployeeSalaryById(si.getId());
            es.setMeritPay(si.getMeritPay());
            es.setNote(si.getNote());
            return es;
        }).collect(Collectors.toList());
        salaryService.saveEmployeeSalaries(ess);
        return true;
    }

    /**
     * 初始化部门员工工资
     * @return
     */
    @PostMapping("/wage/init/dept/{deptId}")
    public boolean initDeptStaffWages(@PathVariable int deptId) {
        // 初始化部门员工工资
        salaryService.initDeptStaffWages(deptId);
        return true;
    }
}
